package com.baizhi.cmfz.aspect;

import cn.hutool.extra.servlet.ServletUtil;
import com.baizhi.cmfz.annotation.LogAnnotation;
import com.baizhi.cmfz.entity.Admin;
import com.baizhi.cmfz.entity.Log;
import com.baizhi.cmfz.service.LogService;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Objects;

@Aspect
@Configuration
public class LogAspect {

    @Autowired
    private LogService logService;

    @After("@annotation(com.baizhi.cmfz.annotation.LogAnnotation)")
    public void logAfter(JoinPoint joinPoint) {
        //1.新建Log对象
        Log log = new Log();
        //2.为属性赋值
        //2.1从session里获取管理员信息
        //获取request

        //获取到当前线程绑定的请求对象 RequestContextHolder可以获取当前请求
        HttpServletRequest request =
                ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))
                        .getRequest();
        //获取session,并从中获取当前管理员
        //Admin admin = (Admin) request.getSession().getAttribute("admin");
        //获取shiro的sessio
        Admin admin = (Admin) SecurityUtils.getSubject().getSession().getAttribute("admin");
        //获取管理员id
        log.setAdminId(admin.getId());
        //2.2获取当前时间
        log.setLogDate(LocalDateTime.now());
        //2.3从当前请求获取当前ip
        String ip = ServletUtil.getClientIP(request);
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        log.setLogIp(ip);
        //操作内容 不同的操作内容不一致-->通过方法传值-->通过注解传值-->通过连接点对象获取方法签名对象-->获取方法对象-->得到方法的注解
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
        //2.4获取操作内容
        String value = annotation.value();
        log.setLogContent(value);
        //2.5获取操作类型
        String type = annotation.type();
        log.setLogType(type);
        logService.addLog(log);
    }

}
